package com.hex.es.annotation;

import com.hex.es.enums.StatisticsTypeEnum;
import org.elasticsearch.search.sort.SortOrder;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * es参数信息与返回信息标注
 * 方法步骤：
 *      步骤一：查询实体类标注
             @Document(indexName = "[index name]", type = "[type name]", refreshInterval = "-1")
            @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
  *     步骤二：在任意方法上标注@EsBuildParamTypeInfo
  *
  * 使用注意点：1、注意参数名与es存储的字段名对应
  *                  即   loanOuterNo -> loan_outer_no √
  *                      loanOuterNos -> loan_outer_no ×
  *            2、文本字段不能用作排序字段
  *            3、分组统计时需 统计字段名（statisticsFieldName）、统计字段别名（statisticsAnotherName）、操作类型（statisticsType）一一对应
  *            4、分页时需rowOffsetFieldName、pageSizeFieldName成对出现
  *            5、分组聚合统计目前只支持一个字段分组
  *            6、分页参数rowOffsetFieldName与mysql的分页不同，mysql是从指定数据行开始向后查size条数据，而es中是指定第几页查size条数据
  *
  * 示例：
  *   1、普通：
        @EsBuildParamTypeInfo(resultType = LoanApplyEs.class)
         LoanApplyEs queryOne(String productCode,String loanOuterNo);

        @EsBuildParamTypeInfo(resultType = LoanApplyEs.class)
        List<LoanApplyEs> queryByList(String productCode, List<String> loanOuterNo);
  *  2、分页
        @EsBuildParamTypeInfo(resultType = RepayApplyEs.class,rangeQueryField = "req_date",fromFieldName = "beginPt",toFieldName = "endPt")
        Integer countByPt(Map<String, Object> condition);
  *  3、分页+范围查询
        @EsBuildParamTypeInfo(resultType = RepayApplyEs.class,orderByField = "req_date",rowOffsetFieldName = "rowOffset",pageSizeFieldName = "pageSize",rangeQueryField = "req_date",fromFieldName = "beginPt",toFieldName = "endPt")
        List<RepayApplyEs> queryAll(Map<String, Object> condition);
  *  4、分组聚合统计
         @EsBuildParamTypeInfo(resultType = RepayPlanStatisticsEs.class,rangeQueryField = "agreed_repay_date",fromFieldName = "beginPt",toFieldName = "endPt",groupByFieldName = "agreed_repay_date",
        statisticsFieldName = {"return_amount","withdraw_amount","due_principal","due_interest","due_charge","paid_principal","paid_interest","paid_charge","base_premium","risk_premium"},
        statisticsAnotherName = {"returnTotalAmount","withdrawTotalAmount","dueTotalPrincipal","dueTotalInterest","dueTotalCharge","paidTotalPrincipal","paidTotalInterest","paidTotalCharge","baseTotalPremium","riskTotalPremium"},
        statisticsType = {StatisticsTypeEnum.SUM,StatisticsTypeEnum.SUM,StatisticsTypeEnum.SUM,StatisticsTypeEnum.SUM,StatisticsTypeEnum.SUM,StatisticsTypeEnum.SUM,StatisticsTypeEnum.SUM,StatisticsTypeEnum.SUM,StatisticsTypeEnum.SUM,StatisticsTypeEnum.SUM,})
        List< RepayPlanStatisticsEs > selectAmountByProductCodeAndFundCode(Map<String, Object> condition);
  *  5、多index、多type查询
        @EsBuildParamTypeInfo(resultType = UserAccountEs.class,types = {"user_account","loan_apply"})
         List<UserAccountEs> findByProductCodeAndThirdUserNo(@Param("productCode") String productCode, @Param("thirdUserNo") String thirdUserNo);
  * @author: hex
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EsBuildParamTypeInfo {

    /**
     * 方法返回具体类型
     * List<T> => T
     * @return
     */
    Class resultType();

    /**
     * 查询指定类型下的数据（支持多类型）
     * @return
     */
    String[] types() default {};

    /**
     * 查询指定索引下的数据（支持多索引查询）
     * @return
     */
    String[] indexs() default {};

    /**
     * 指定需要排序的字段名
     * @return
     */
    String orderByField() default "";

    /**
     * 排序：降序or升序
     * @return
     */
    SortOrder orderDirection() default SortOrder.DESC;

    /**
     * 指定分页参数（当前页）在参数里的变量名
     * @return
     */
    String rowOffsetFieldName() default "";

    /**
     * 指定分页参数（每页数量）在参数里的变量名
     * @return
     */
    String pageSizeFieldName() default "";

    /**
     * 指定使用or条件的字段
     * @return
     */
    String[] shouldField() default {};

    /**
     * 范围查询字段名，需要和fromFieldName与toFieldName关联配套使用
     * @return
     */
    String[] rangeQueryField() default {};

    /**
     * 范围查询起始参数名
     * @return
     */
    String[] fromFieldName() default {};

    /**
     * 范围查询结束参数名
     * @return
     */
    String[] toFieldName() default {};

    /**
     * group by的字段名
     * @return
     */
    String groupByFieldName() default "";

    /**
     * 需要统计的字段名  需要和statisticsAnotherName与statisticsType关联配套使用
     * @return
     */
    String[] statisticsFieldName() default {};

    /**
     * 查出时 统计字段的别名
     * @return
     */
    String[] statisticsAnotherName() default {};

    /**
     * 统计类型
     * @return
     */
    StatisticsTypeEnum[] statisticsType() default {};
}
